﻿//////////////////////////////////////////////////////////////////
//
// Factory.cs
//
// Copyright (c) 2012 Dan Pike. All rights reserved
//
// Refer to license.txt for any license restrictions.
// 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Entities
{
   public abstract class Factory : Entity
   {
      //////////////////////////////////////////////////////////////////////////
      //
      public Factory(World world)
         : base(world)
      {
      }

      //////////////////////////////////////////////////////////////////////////
      // Sequencing for the SortedDictionary. If x depends on materials produced
      // by y, then x.precedence < y.precedence
      internal enum Precedences
      {
         None,
         Beekeeper,
         Brewery,
         Claypit,
         Dairy,
         GrainFarm,
         HempFarm,
         MeadBrewery,
         Sawmill,
         Pitchmaker,
         Saltworks,
         SheepFarm,
         Smelter,
         Smokehouse,
         StockFarm,
         Toolworks,
         HuntingLodge,
         Weaver,
         Tailor,
         Winery,
      }
      internal abstract Precedences precedence { get; }

      //////////////////////////////////////////////////////////////////////////
      //
      public Dictionary<Material, double> inputs
      {
         get { return inputs_; }
      }

      //////////////////////////////////////////////////////////////////////////
      //
      public bool isRequiredFor(Material product)
      {
         try
         {
            // Returns true if this factory is in the chain of production that
            // results in "product"
            return (output == product) ||
               inputs.Keys.Any(material => material.producer.isRequiredFor(product));
         }
         catch (System.Exception ex)
         {
            logger_.exception(ex);
         }
         return false;
      }

      //////////////////////////////////////////////////////////////////////////
      //
      public Material output
      {
         get { return output_; }
         internal set
         {
            output_ = value;
            output_.producer = this;
         }
      }

      //////////////////////////////////////////////////////////////////////////
      //
      public bool getInProductionChain(Material material)
      {
         try
         {
            return (output == material) || inputs.Keys.Any(input =>
               (null != input.producer) && input.producer.getInProductionChain(material));
         }
         catch (System.Exception ex)
         {
            logger_.exception(ex);
         }
         return false;
      }

      //////////////////////////////////////////////////////////////////////////
      //
      public Dictionary<Material, double> inputs_ = new Dictionary<Material, double>();   // map the Almanac material to the count for each output count
      private Material output_;  // The Almanac material's count is the production rate
   }
}
